import React, { createContext, useContext, useState, useEffect, useCallback, useRef } from 'react';
import { useNavigate } from 'react-router-dom';
import axios from 'axios';

// 类型定义
interface User {
  id: string;
  email: string;
  name: string;
  avatar: string;
  role: 'user' | 'admin';
  createdAt: string;
  updatedAt: string;
}

interface AuthContextType {
  user: User | null;
  loading: boolean;
  error: string | null;
  login: (email: string, password: string) => Promise<void>;
  signup: (email: string, password: string, name: string) => Promise<void>;
  logout: () => void;
  isAuthenticated: boolean;
}

// 创建Context
const AuthContext = createContext<AuthContextType | undefined>(undefined);

// 自定义Hook
export const useAuth = () => {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuth必须在AuthProvider内使用');
  }
  return context;
};

// 防重复点击锁
const useSubmitLock = () => {
  const isSubmitting = useRef(false);

  const withLock = async (fn: () => Promise<void>) => {
    if (isSubmitting.current) return;
    isSubmitting.current = true;
    try {
      await fn();
    } finally {
      isSubmitting.current = false;
    }
  };

  return withLock;
};

// Provider组件
export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const navigate = useNavigate();
  const submitLock = useSubmitLock();

  // 获取CSRF令牌
  const getCsrfToken = () => {
    const name = 'XSRF-TOKEN=';
    const decodedCookie = decodeURIComponent(document.cookie);
    const cookieArray = decodedCookie.split(';');
    for (let cookie of cookieArray) {
      cookie = cookie.trim();
      if (cookie.indexOf(name) === 0) {
        return cookie.substring(name.length, cookie.length);
      }
    }
    return '';
  };

  // 初始化时验证token
  useEffect(() => {
    verifyToken();
  }, []);

  // 验证token
  const verifyToken = useCallback(async () => {
    try {
      const response = await axios.get('/auth/me', {
        withCredentials: true, // 启用跨域凭证
        headers: {
          'X-XSRF-TOKEN': getCsrfToken()
        }
      });
      setUser(response.data);
      setError(null);
    } catch (err) {
      setUser(null);
      setError('登录已过期，请重新登录');
    } finally {
      setLoading(false);
    }
  }, []);

  // 登录方法
  const login = async (email: string, password: string) => {
    await submitLock(async () => {
      try {
        setLoading(true);
        setError(null);
        const response = await axios.post('/auth/login', 
          { email, password },
          {
            withCredentials: true,
            headers: {
              'X-XSRF-TOKEN': getCsrfToken()
            }
          }
        );
        setUser(response.data.user);
        navigate('/dashboard');
      } catch (err) {
        if (axios.isAxiosError(err) && err.response) {
          setError(err.response.data.message || '登录失败');
        } else {
          setError('登录失败，请稍后重试');
        }
        throw err;
      } finally {
        setLoading(false);
      }
    });
  };

  // 注册方法
  const signup = async (email: string, password: string, name: string) => {
    await submitLock(async () => {
      try {
        setLoading(true);
        setError(null);
        const response = await axios.post('/auth/signup', 
          { email, password, name },
          {
            withCredentials: true,
            headers: {
              'X-XSRF-TOKEN': getCsrfToken()
            }
          }
        );
        setUser(response.data.user);
        navigate('/dashboard');
      } catch (err) {
        if (axios.isAxiosError(err) && err.response) {
          setError(err.response.data.message || '注册失败');
        } else {
          setError('注册失败，请稍后重试');
        }
        throw err;
      } finally {
        setLoading(false);
      }
    });
  };

  // 登出方法
  const logout = useCallback(async () => {
    try {
      await axios.post('/auth/logout', {}, {
        withCredentials: true,
        headers: {
          'X-XSRF-TOKEN': getCsrfToken()
        }
      });
    } catch (err) {
      console.error('登出失败:', err);
    } finally {
      setUser(null);
      setError(null);
      navigate('/');
    }
  }, [navigate]);

  // 路由变化时验证token
  useEffect(() => {
    verifyToken();
  }, [verifyToken]);

  const value = {
    user,
    loading,
    error,
    login,
    signup,
    logout,
    isAuthenticated: !!user
  };

  return (
    <AuthContext.Provider value={value}>
      {children}
    </AuthContext.Provider>
  );
}; 